import React, { ChangeEvent, Component, FormEvent } from 'react'
import styles from "./index.module.css";
import logo from "@image/logo.png";
import { z, ZodError } from "zod";
import { loginRequest } from '@src/requests/auth';
import { RouteComponentProps } from 'react-router-dom';
import {connect, MapDispatchToPropsParam} from 'react-redux'
import { AppThunkDispatch } from '@src/index';
import { UserActions } from '@src/store/actions/userActions';
import { Credentials } from '@src/store/reducers/userReducer';
import { UserCreators } from '@src/store/creators/userCreators';
import { toast } from "react-toastify";
//表单状态
export interface FormState{
  mobile:string;
  code:string;
  agree:boolean
}


//表单验证错误信息
interface FormError{
  mobile?:string[]
  code?:string[]
  agree?:string[]
}



interface States{
  formState:FormState
  formError:FormError
}



// 创建表单验证规则
const formSchema = z.object({
  mobile: z
    .string()
    .min(1, "请输入手机号")
    .regex(/^1[3-9]\d{9}$/, "手机号格式不正确"),
  code: z
    .string()
    .min(1, "请输入验证码")
    .regex(/^\d{6}$/, "验证码格式不正确"),
  agree: z.literal(true, {
    errorMap: () => ({ message: "请勾选用户协议和隐私条款" }),
  }),
});


interface DispatchProps{
   //保存用户登录凭据
   saveCredentials (credentials:Credentials):UserActions.SaveCredentials
}

interface OwnProps{}


type Props = RouteComponentProps & OwnProps & DispatchProps 

 class LoginPage extends Component<Props,States> {


constructor(props:Readonly<Props>){
  super(props)

  this.state={
    //记录表单状态
    formState:{
      mobile:"13911111111",
      code:"246810",
      agree:true
    },
    // 记录表单验证错误
    formError:{}
  }
}


//表单提交
onSubmit = (event:FormEvent<HTMLFormElement>) =>{
 // 阻止表单提交默认跳转的行为
 event.preventDefault();

 //捕获表单验证错误
 try{
  //如果验证失败,报错
  //如果验证成功,返回验证对象
  formSchema.parse(this.state.formState)


  //发送登录请求
  loginRequest({
    mobile:this.state.formState.mobile,
    code:this.state.formState.code
  }).then((response)=>{

    
    //保存用户登录凭据
   this.props.saveCredentials(response.data)

   //用户登录提示
   toast.success("登录成功", { position: "top-center", autoClose: 2000 });

    //跳转到后台管理的首页
    this.props.history.push('/admin/dashboard')
  })
 }catch(error){
  //设置error参数的类型，此处传递泛型参数的意义在于代码提示
  const zodError = error as ZodError<FormError>
  //保存失败信息
  this.setState({formError:zodError.formErrors.fieldErrors})
 }
}


//更新表单状态
updateFormState = (event:ChangeEvent<HTMLInputElement>) =>{
this.setState({
  formState:{
    ...this.state.formState,
    [event.target.name]:event.target.name==='agree' ? event.target.checked : event.target.value
  }
})
}


//渲染错误信息
renderErrors = (field:keyof FormState) =>{
  return this.state.formError[field] && <p className="help is-danger">{this.state.formError[field]?.[0]}</p>
}


//表单验证
validateField = <T extends keyof FormState>(name:T,value:FormState[T]) =>{
  try{
    //验证
    formSchema.shape[name].parse(value)

  }catch(error){
    //为错误对象设置类型
    const zodError = error as ZodError<FormError>
    //保存错误信息

    this.setState({
      formError:{
        ...this.state.formError,
        [name]:zodError.formErrors.formErrors
      }
    })

  }
}



  render() {
    
    return (
      <div className={styles.loginPage}>
        <div className={styles.loginContainer}>
          <img className={styles.logo} src={logo} alt="极客园" />
          <form onSubmit={this.onSubmit}>
            <div className="field">
              <input className="input" type="text" placeholder="请输入手机号" value={this.state.formState.mobile} onChange={this.updateFormState} onInput={(event)=>{
                this.validateField('mobile',event.currentTarget.value)
              }} name="mobile"/>
              {this.renderErrors('mobile')}
            </div>
            <div className="field">
              <input className="input" type="text" placeholder="请输入验证码" value={this.state.formState.code} onChange={this.updateFormState}  onInput={(event)=>{
                this.validateField('code',event.currentTarget.value)
              }} name="code"/>
              {this.renderErrors("code")}
            </div>
            <div className="field">
              <label className="checkbox">
                <input type="checkbox" checked={this.state.formState.agree} onChange={this.updateFormState} onInput={(event)=>{
                  this.validateField('agree',event.currentTarget.checked) 
                }} name="agree"/>
                <span className="is-size-7 ml-1">
                  我已阅读并同意「用户协议」和「隐私条款」
                </span>
              </label>
              {this.renderErrors("agree")}
            </div>
            <div className="field">
              <button className="button is-info is-fullwidth">登录</button>
            </div>
          </form>
        </div>
      </div>
    );
  }
}


const mapDispatchToProps:MapDispatchToPropsParam<DispatchProps,OwnProps> = (dispatch:AppThunkDispatch) =>({

  saveCredentials(credentials) {
    return dispatch(UserCreators.saveCredentials(credentials))
  },
 })

const mapStateToProps = () =>({})

export default connect(mapStateToProps,mapDispatchToProps)(LoginPage)
